﻿#region Copyright and License
/*==============================================================================
 *  Copyright (c) www.51mvc.com Corporation.  All rights reserved.
 * ===============================================================================
 * This code and information is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the implied warranties
 * of merchantability and fitness for a particular purpose.
 * ===============================================================================
 * Licensed under the GNU General Public License (GPL) v2
 * http://www.51mvc.com/
 * Create By 小鱼(Leven)  - http://leven.com.cn
 * ==============================================================================*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using Microsoft.Practices.Unity;

namespace Infancy.Core.Container.Unity {
    public class UnityContainer : ContainerBase {
        private static object lockObject = new object();
        private static Dictionary<string, IUnityContainer> cache = new Dictionary<string, IUnityContainer>();
        private static ContainerType type = ContainerType.Unity;

        public UnityContainer(string name)
            : base(name) {
        }

        private IUnityContainer container;

        public override void Initialize() {
            OnInitializing(new ContainerEventsArgs(this, type));
            IUnityContainer currentContainer = null;
            if (!cache.TryGetValue(Name, out currentContainer)) {
                lock (lockObject) {
                    currentContainer = new Microsoft.Practices.Unity.UnityContainer();
                    object obj = ConfigurationManager.GetSection("unity");
                    if (obj == null || !(obj is Microsoft.Practices.Unity.Configuration.UnityConfigurationSection)) {
                        throw new ConfigurationErrorsException("section unity error.");
                    }
                    Microsoft.Practices.Unity.Configuration.UnityConfigurationSection section = obj as Microsoft.Practices.Unity.Configuration.UnityConfigurationSection;
                    section.Containers[Name].Configure(currentContainer);
                    cache.Add(Name, currentContainer);
                }
            }
            container = currentContainer;
            OnInitializing(new ContainerEventsArgs(this, type));
        }

        public override T Resolve<T>() {
            try {
                if (container == null) {
                    Initialize();
                }
                return container.Resolve<T>();
            } catch (Exception e) {
                OnResolveFailed(new ContainerFailedEventsArgs(this, new ContainerException(e.Message, type, Name, e)));
                throw e;
            }
        }

        public override void TearDown() {
            OnTearDowning(new ContainerEventsArgs(this, type));
            lock (lockObject) {
                if (container != null) {
                    container.Dispose();
                    cache.Remove(Name);
                }
            }
            OnTearDowed(new ContainerEventsArgs(this, type));
        }
    }
}
